package com.zbkj.crmeb.store.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.constants.Constants;
import com.crmeb.core.common.CommonResult;
import com.crmeb.core.exception.CrmebException;
import com.crmeb.core.utils.RedisUtil;
import com.crmeb.core.utils.TableNameUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.utils.ProductUtil;
import com.utils.StoreProductMerUtil;
import com.zbkj.crmeb.authorization.model.TokenModel;
import com.zbkj.crmeb.chant.model.CategoryMatch;
import com.zbkj.crmeb.chant.model.ChannelMerchant;
import com.zbkj.crmeb.chant.service.ICategoryMatchService;
import com.zbkj.crmeb.chant.service.IChannelMerchantService;
import com.zbkj.crmeb.enums.PriceTypeEnum;
import com.zbkj.crmeb.enums.StockAreaTempEnum;
import com.zbkj.crmeb.express.service.ShippingTemplatesService;
import com.zbkj.crmeb.front.request.IndexStoreProductSearchRequest;
import com.zbkj.crmeb.merchant.admin.service.MerStoreProductService;
import com.zbkj.crmeb.store.dao.StoreProductDao;
import com.zbkj.crmeb.store.dao.StoreProductMerDao;
import com.zbkj.crmeb.store.dao.StoreProductValueMerDao;
import com.zbkj.crmeb.store.model.StoreProduct;
import com.zbkj.crmeb.store.model.StoreProductAttrValue;
import com.zbkj.crmeb.store.model.StoreProductMer;
import com.zbkj.crmeb.store.model.StoreProductValueMer;
import com.zbkj.crmeb.store.request.*;
import com.zbkj.crmeb.store.response.StoreProductAttrValueResponse;
import com.zbkj.crmeb.store.response.StoreProductNormResponse;
import com.zbkj.crmeb.store.response.StoreProductResponse;
import com.zbkj.crmeb.store.service.*;
import com.zbkj.crmeb.store.vo.StoreProductMerVo;
import com.zbkj.crmeb.system.model.SystemConfig;
import com.zbkj.crmeb.system.service.SystemConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MerchantStoreProductServiceImpl extends ServiceImpl<StoreProductMerDao, StoreProductMer> implements StoreProductMerService {
    @Resource
    StoreProductMerDao storeProductMerDao;
    @Resource
    StoreProductService storeProductService;
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    MarkupRateService markupRate;
    @Autowired
    StoreProductValueMerService storeProductValueMerService;
    @Resource
    IChannelMerchantService channelMerchantService;
    @Autowired
    StoreProductAttrValueService storeProductAttrValueService;
    @Autowired
    private ShippingTemplatesService shippingTemplatesService;

    @Autowired
    @Lazy
    private StoreProductMerUtil storeProductMerUtil;

    @Resource
    private StoreProductValueMerDao storeProductValueMerDao;

    @Autowired
    private ICategoryMatchService categoryMatchService;

    @Resource
    private StoreProductDao storeProductDao;

    @Autowired
    private MerStoreProductService merStoreProductService;

    @Autowired
    private SystemConfigService systemConfigService;

    @Autowired
    @Lazy
    ProductUtil productUtil;

    /**
     * 批量上架/下架
     *
     * @param token
     * @param vo
     * @return
     */
    @Override
    public Boolean batchEnabled(String token, BatchEnabledRequest vo) {
        Object merId = redisUtil.get(StrUtil.format(Constants.ADMIN_TOKEN_MER_KEY, token));
        Object userId = redisUtil.get(TokenModel.TOKEN_REDIS + token);
        if (null != merId && null != userId) {
            vo.getProductIdList().forEach(e -> {
                StoreProduct storeProduct = storeProductService.getById(e);
                StoreProductMer storeMerProduct = storeProductMerDao.selectOne(Wrappers.<StoreProductMer>lambdaQuery()
                        .eq(StoreProductMer::getProductId, e)
                        .last("LIMIT 1")
                );
                if (null == storeMerProduct) {
                    storeMerProduct = new StoreProductMer();
                    storeMerProduct.setProductId(e);
                    storeMerProduct.setIsNotShow(vo.getIsNotShow());
                    storeMerProduct.setIsSystemOut(0);
                    storeMerProduct.setCreateTime(new Date());
                    storeMerProduct.setUpdateTime(new Date());
                    storeProductMerDao.insert(storeMerProduct);
                } else {
                    storeMerProduct.setIsNotShow(vo.getIsNotShow());
                    storeMerProduct.setIsSystemOut(0);
                    storeMerProduct.setUpdateTime(new Date());


                    if ("0".equals(vo.getIsNotShow())) {    //上架的时候

                        //2023.6.5判断运费模板信息
                        if (StockAreaTempEnum.CN.getTempId().equals(storeProduct.getTempId())) {

                            if (ObjectUtil.isNull(storeMerProduct.getShippingTempId())) {
                                throw new CrmebException("请先填写对应运费模板信息!");
                            }
                        }
                    }

                    storeProductMerDao.updateById(storeMerProduct);
                }
                if (Objects.equals(storeProduct.getMerId().toString(), merId.toString())) {
                    storeProduct.setIsShow(!Objects.equals(storeMerProduct.getIsNotShow(), "1"));
                    storeProductService.updateById(storeProduct);
                }
            });
        } else {
            throw new CrmebException("用户未绑定商户");
        }
        return true;
    }

    /**
     * 批量上架/下架
     *
     * @param token
     * @param vo
     * @return
     */
    @Override
    public Boolean batchBest(String token, BestEnabledRequest vo) {
        Object merId = redisUtil.get(StrUtil.format(Constants.ADMIN_TOKEN_MER_KEY, token));
        Object userId = redisUtil.get(TokenModel.TOKEN_REDIS + token);
        if (null != merId && null != userId) {
            vo.getProductIdList().forEach(e -> {
                StoreProductMer storeMerProduct = storeProductMerDao.selectOne(Wrappers.<StoreProductMer>lambdaQuery()
                        .eq(StoreProductMer::getProductId, e)
                        .last("LIMIT 1")
                );
                if (null == storeMerProduct) {
                    storeMerProduct = new StoreProductMer();
                    storeMerProduct.setProductId(e);
                    storeMerProduct.setIsBest(vo.getIsBest());
                    storeMerProduct.setBestTime(new Date());
                    storeMerProduct.setCreateTime(new Date());
                    storeMerProduct.setUpdateTime(new Date());
                    storeProductMerDao.insert(storeMerProduct);
                } else {
                    storeMerProduct.setIsBest(vo.getIsBest());
                    storeMerProduct.setBestTime(new Date());
                    storeMerProduct.setUpdateTime(new Date());
                    storeProductMerDao.updateById(storeMerProduct);
                }
            });
        } else {
            throw new CrmebException("用户未绑定商户");
        }
        return true;
    }

    /**
     * 禁用
     */
    @Override
    public Boolean enabled(String token, StoreProductMerVo vo) {
        StoreProduct product = storeProductService.getById(vo.getProductId());
        if (null == product) {
            throw new CrmebException("该商品不存在!");
        }
        if (Objects.equals(vo.getIsNotShow(), "0") && product.getStock() <= 0) {
            throw new CrmebException("该商品已售馨!");
        }

        //2023.6.2判断运费模板信息
        //如果是自建商品
        if (!productUtil.checkShippingTemp(product)) {
            throw new CrmebException("请先填写对应运费模板信息!");
        }

        Object merId = redisUtil.get(StrUtil.format(Constants.ADMIN_TOKEN_MER_KEY, token));
        Object userId = redisUtil.get(TokenModel.TOKEN_REDIS + token);
        if (null != merId && null != userId) {
            StoreProductMer storeMerProduct = storeProductMerDao.selectOne(Wrappers.<StoreProductMer>lambdaQuery()
                    .eq(StoreProductMer::getProductId, vo.getProductId())
                    .last("LIMIT 1")
            );
            if (null == storeMerProduct) {
                storeMerProduct = new StoreProductMer();
                storeMerProduct.setProductId(vo.getProductId());
                storeMerProduct.setIsNotShow(vo.getIsNotShow());
                storeMerProduct.setIsSystemOut(0);
                storeMerProduct.setCreateTime(new Date());
                storeMerProduct.setUpdateTime(new Date());
                storeProductMerDao.insert(storeMerProduct);
            } else {
                storeMerProduct.setIsNotShow(vo.getIsNotShow());
                storeMerProduct.setIsSystemOut(0);
                storeMerProduct.setUpdateTime(new Date());
                storeProductMerDao.updateById(storeMerProduct);
            }
            if (product.getIsEurope() == 1) {
                product.setIsShow(Objects.equals(storeMerProduct.getIsNotShow(), "0"));
                storeProductService.updateById(product);
            }
        } else {
            throw new CrmebException("用户未绑定商户");
        }

        return true;
    }

    /**
     * 小编推荐
     */
    @Override
    public Boolean best(String token, StoreProductMerVo vo) {
        Object merId = redisUtil.get(StrUtil.format(Constants.ADMIN_TOKEN_MER_KEY, token));
        Object userId = redisUtil.get(TokenModel.TOKEN_REDIS + token);

        if (null != merId && null != userId) {
            StoreProductMer storeMerProduct = storeProductMerDao.selectOne(Wrappers.<StoreProductMer>lambdaQuery()
                    .eq(StoreProductMer::getProductId, vo.getProductId())
                    .last("LIMIT 1")
            );
            if (null == storeMerProduct) {
                storeMerProduct = new StoreProductMer();
                storeMerProduct.setProductId(vo.getProductId());
                storeMerProduct.setIsBest(vo.getIsBest());
                storeMerProduct.setBestTime(new Date());
//                storeMerProduct.setCreateTime(new Date());
//                storeMerProduct.setUpdateTime(new Date());
                storeProductMerDao.insert(storeMerProduct);
            } else {
                storeMerProduct.setIsBest(vo.getIsBest());
                storeMerProduct.setBestTime(new Date());
//                storeMerProduct.setUpdateTime(new Date());
                storeProductMerDao.updateById(storeMerProduct);
            }
        } else {
            throw new CrmebException("用户未绑定商户");
        }

        return true;
    }

    /**
     * 批量修改佣金比例
     */

    /**
     * 批量上架/下架
     *
     * @param token
     * @param vo
     * @return
     */
    @Override
    public Boolean batchEditRebateRate(String token, BatchEditRebateRateRequest vo) {
        Object merId = redisUtil.get(StrUtil.format(Constants.ADMIN_TOKEN_MER_KEY, token));
        Object userId = redisUtil.get(TokenModel.TOKEN_REDIS + token);
        if(vo.getRebateRate() == null || vo.getRebateRate().compareTo(BigDecimal.ZERO) <= 0){
            throw new CrmebException("请填写大于0的佣金比例!");
        }
        if (null != merId && null != userId) {
            vo.getProductIdList().forEach(e -> {
                StoreProduct storeProduct = storeProductService.getById(e);
                StoreProductMer storeMerProduct = storeProductMerDao.selectOne(Wrappers.<StoreProductMer>lambdaQuery()
                        .eq(StoreProductMer::getProductId, e)
                        .last("LIMIT 1")
                );
                if (null == storeMerProduct) {
                    storeMerProduct = new StoreProductMer();
                    storeMerProduct.setProductId(e);
                    storeMerProduct.setRebateRate(vo.getRebateRate());
                    storeMerProduct.setCreateTime(new Date());
                    storeMerProduct.setUpdateTime(new Date());
                    storeProductMerDao.insert(storeMerProduct);
                } else {
                    storeMerProduct.setRebateRate(vo.getRebateRate());
                    storeMerProduct.setUpdateTime(new Date());

                    storeProductMerDao.updateById(storeMerProduct);
                }
                if (Objects.equals(storeProduct.getMerId().toString(), merId.toString())) {
                    storeProduct.setRebateRate(vo.getRebateRate());
                    storeProductService.updateById(storeProduct);
                }
            });
        } else {
            throw new CrmebException("用户未绑定商户");
        }
        return true;
    }

    /**
     * 查询上架商品列表
     */
    @Override
    public List<Integer> selectProductIdList(StoreProductMerVo vo) {
        LambdaQueryWrapper<StoreProductMer> queryWrapper = new LambdaQueryWrapper<StoreProductMer>();
        if (StringUtils.isNotBlank(vo.getIsNotShow())) {
            queryWrapper.eq(StoreProductMer::getIsNotShow, vo.getIsNotShow());
        }
        if (!Objects.isNull(vo.getIsBest())) {
            queryWrapper.eq(StoreProductMer::getIsBest, vo.getIsBest());
        }
        List<StoreProductMer> merchantStoreProductList = storeProductMerDao.selectList(queryWrapper);
        if (null != merchantStoreProductList && merchantStoreProductList.size() > 0) {
            return merchantStoreProductList.stream().map(StoreProductMer::getProductId).collect(Collectors.toList());
        }
        return null;
    }

    /**
     * 查询推荐商品列表
     */
//    @Override
//    public List<Integer> selectProductBestIdList(StoreProductMerVo vo) {
//        List<StoreProductMer> merchantStoreProductList = storeProductMerDao.selectProductBestIdList(vo);
//        if(null!=merchantStoreProductList && merchantStoreProductList.size()>0){
//            return merchantStoreProductList.stream().map(StoreProductMer::getProductId).collect(Collectors.toList());
//        }
//        return null;
//    }

    /**
     * 更新云仓商品数据
     */
    @Override
    public Boolean updateByCloud(StoreProductMerRequest storeProductMerRequest, Integer merId) {
        List<StoreProductMer> storeProductMers = storeProductMerRequest.getStoreProductMers();
        List<StoreProductMer> storeProductMerSaves = new ArrayList<>();
        for (StoreProductMer merRequest : storeProductMers) {
            StoreProductMer storeProductMer = storeProductMerDao.selectOne(Wrappers.<StoreProductMer>lambdaQuery()
                    .eq(StoreProductMer::getProductId, merRequest.getProductId())
                    .last("LIMIT 1")
            );
            storeProductMer = null == storeProductMer ? new StoreProductMer() : storeProductMer;
            storeProductMer.setProductId(merRequest.getProductId());
            storeProductMer.setRecommendImg(merRequest.getRecommendImg());

            if (Objects.equals(merRequest.getPriceType(), PriceTypeEnum.FIXED.getCode()) && CollectionUtils.isNotEmpty(merRequest.getStoreProductValueMerList())) {
                List<StoreProductValueMer> productValueMerList = new ArrayList<>();
                for (StoreProductValueMer storeProductValueMer : merRequest.getStoreProductValueMerList()) {
                    StoreProductValueMer productValueMer = Optional.ofNullable(storeProductValueMerService.getOne(
                            Wrappers.lambdaQuery(StoreProductValueMer.class)
                                    .eq(StoreProductValueMer::getProductId, merRequest.getProductId())
                                    .eq(StoreProductValueMer::getSourceSkuId, storeProductValueMer.getSourceSkuId())
                                    .orderByDesc(StoreProductValueMer::getUpdateTime)
                                    .last("LIMIT 1")))
                            .orElse(new StoreProductValueMer());
                    if (storeProductValueMer.getPrice() == null) {
                        throw new CrmebException("商品sku售价:" + merRequest.getPrice() + "不能为空");
                    }
                    if (BigDecimal.ZERO.compareTo(storeProductValueMer.getPrice()) > 0) {
                        throw new CrmebException("商品sku售价:" + merRequest.getPrice() + "不能低于0元");
                    }
                    productValueMer.setProductId(merRequest.getProductId())
                            .setSourceSkuId(storeProductValueMer.getSourceSkuId())
                            .setPrice(storeProductValueMer.getPrice());
//                    productValueMer.setWeight(storeProductValueMer.getWeight());
                    productValueMer.setVolume(storeProductValueMer.getVolume());
                    productValueMerList.add(productValueMer);
                }
                //查询sku实时库存,获取最低价格
                List<StoreProductAttrValue> storeProductAttrValueList = storeProductAttrValueService.list(Wrappers.lambdaQuery(StoreProductAttrValue.class).eq(StoreProductAttrValue::getProductId, merRequest.getProductId()).gt(StoreProductAttrValue::getStock, 0));
                List<String> list = storeProductAttrValueList.stream().map(StoreProductAttrValue::getSourceSkuId).collect(Collectors.toList());
                BigDecimal minPrice;
                if (CollectionUtils.isNotEmpty(list)) {
                    minPrice = merRequest.getStoreProductValueMerList().stream().filter(e -> list.contains(e.getSourceSkuId())).map(StoreProductValueMer::getPrice).filter(Objects::nonNull).min(BigDecimal::compareTo).orElse(BigDecimal.ZERO);
                } else {
                    minPrice = merRequest.getStoreProductValueMerList().stream().map(StoreProductValueMer::getPrice).filter(Objects::nonNull).min(BigDecimal::compareTo).orElse(BigDecimal.ZERO);
                }
                storeProductMer.setPrice(minPrice);
                storeProductValueMerService.saveOrUpdateBatch(productValueMerList);
                storeProductMer.setPriceType(merRequest.getPriceType());
                storeProductMer.setShippingTempId(merRequest.getShippingTempId());
            }
            storeProductMerSaves.add(storeProductMer);
        }

        return this.saveOrUpdateBatch(storeProductMerSaves);
    }

    /**
     * 云仓商品批量加价
     */
    @Override
    public Boolean raiseByCloud(List<Integer> productIds, BigDecimal price, Integer merId) {

        List<StoreProductMer> storeProductMerSaves = new ArrayList<>();
        for (Integer id : productIds) {
            StoreProductMer storeProduct = storeProductMerDao.selectOne(Wrappers.<StoreProductMer>lambdaQuery()
                    .eq(StoreProductMer::getProductId, id)
                    .last("LIMIT 1")
            );
            storeProduct = null == storeProduct ? new StoreProductMer() : storeProduct;
            storeProduct.setProductId(id);
            storeProduct.setPrice(price);
            storeProduct.setPriceType(PriceTypeEnum.RAISE.getCode());
            storeProductMerSaves.add(storeProduct);
        }

        return this.saveOrUpdateBatch(storeProductMerSaves);
    }

    @Override
    public List<StoreProduct> getProductIdList(IndexStoreProductSearchRequest request) {
        return storeProductMerDao.getProductIdList(request);
    }

    /**
     * 批量设置运费模板
     *
     * @param request
     * @param merId
     * @return
     */
    @Override
    public CommonResult<Object> batchUpdateShipTemp(BatchUpdateShipTempRequest request, Integer merId) {
        synchronized (merId.toString().intern()) {
            if (CollectionUtils.isEmpty(request.getProductIdList())) {
                throw new CrmebException("要修改数据不能为空!");
            }
            //判断参数类型
            List<StoreProduct> productList = storeProductService.list(Wrappers.lambdaQuery(StoreProduct.class).in(StoreProduct::getId, request.getProductIdList()).select(StoreProduct::getIsEurope, StoreProduct::getId));
            boolean anyMatch = productList.stream().anyMatch(e -> e.getIsEurope() == 1 && e.getConvertIsEurope() == null);
            if (anyMatch && request.getProductType() != 2) {
                log.error("----------批量设置运费模板异常,请求参数:---------------" + request.toString());
                throw new CrmebException("参数异常");
            }
            if (!anyMatch && request.getProductType() != 1) {
                log.error("----------批量设置运费模板异常,请求参数:---------------" + request.toString());
                throw new CrmebException("参数异常");
            }
            boolean allMatch = productList.stream().allMatch(e -> e.getIsEurope() == 1 && e.getConvertIsEurope() == null);
            if (anyMatch && !allMatch) {
                log.error("----------批量设置运费模板异常,请求参数:---------------" + request.toString());
                throw new CrmebException("商品id集合参数异常");
            }
            List<Integer> ids = request.getProductIdList();
            if (1 == request.getProductType()) {
                //云参商品修改运费模板
                List<StoreProductMer> productMers = new ArrayList<>();
                List<StoreProductMer> storeProductMers = storeProductMerDao.selectList(Wrappers.<StoreProductMer>lambdaQuery()
                        .in(StoreProductMer::getProductId, ids)
                );
                Map<Integer, StoreProductMer> storeProductMerMap = storeProductMers.stream().collect(Collectors.toMap(StoreProductMer::getProductId, Function.identity(), (key1, key2) -> key2));
                for (Integer id : ids) {
                    StoreProductMer storeProduct = storeProductMerMap.get(id);
                    storeProduct = null == storeProduct ? new StoreProductMer() : storeProduct;
                    storeProduct.setProductId(id);
                    storeProduct.setShippingTempId(request.getTemplateId());
                    storeProduct.setUpdateTime(new Date());
                    productMers.add(storeProduct);
                }

                boolean update = this.saveOrUpdateBatch(productMers);
                return update ? CommonResult.success() : CommonResult.failed();
            } else {
                //自建商品修改运费模板
                List<StoreProduct> products = new ArrayList<>();
                for (Integer id : ids) {
                    StoreProduct storeProduct = new StoreProduct();
                    storeProduct.setId(id);
                    storeProduct.setShippingTempId(request.getTemplateId());
                    storeProduct.setUpdateTime(new Date());
                    products.add(storeProduct);
                }
                boolean update = storeProductService.saveOrUpdateBatch(products);
                return update ? CommonResult.success() : CommonResult.failed();
            }
        }
    }

    /**
     * 批量修改价格
     *
     * @param request
     * @param merId
     * @return
     */
    @Override
    public CommonResult<Object> batchUpdatePrice(BatchUpdatePriceRequest request, Integer merId) {
        synchronized (merId.toString().intern()) {
            if (CollectionUtils.isEmpty(request.getProductIdList())) {
                throw new CrmebException("要修改数据不能为空!");
            }
            //判断参数类型
            List<StoreProduct> productList = storeProductService.list(Wrappers.lambdaQuery(StoreProduct.class).in(StoreProduct::getId, request.getProductIdList()).select(StoreProduct::getIsEurope, StoreProduct::getId));
            boolean anyMatch = productList.stream().anyMatch(e -> e.getIsEurope() == 1 && e.getConvertIsEurope() == null);
            if (anyMatch && request.getProductType() != 2) {
                log.error("----------批量修改价格异常,请求参数:---------------" + request.toString());
                throw new CrmebException("参数异常");
            }
            if (!anyMatch && request.getProductType() != 1) {
                log.error("----------批量修改价格异常,请求参数:---------------" + request.toString());
                throw new CrmebException("参数异常");
            }
            boolean allMatch = productList.stream().allMatch(e -> e.getIsEurope() == 1 && e.getConvertIsEurope() == null);
            if (anyMatch && !allMatch) {
                log.error("----------批量修改价格异常,请求参数:---------------" + request.toString());
                throw new CrmebException("商品id集合参数异常");
            }
            if (request.getType() != 1) {
                if (request.getProductType() == 2 && PriceTypeEnum.MARKUP.getCode().equals(request.getType())) {
                    throw new CrmebException("自建商品不能使用加价率");
                }
                if (request.getType() != 0 && null == request.getRatio()) {
                    throw new CrmebException("加价率/折扣不能为空");
                }
                //加价率
                if (PriceTypeEnum.MARKUP.getCode().equals(request.getType()) && new BigDecimal("-100").compareTo(request.getRatio()) > 0) {
                    throw new CrmebException("加价率不得输入小于等于-100的数字");
                }
                //折扣加价
                if (PriceTypeEnum.DISCOUNT.getCode().equals(request.getType()) && BigDecimal.ZERO.compareTo(request.getRatio()) > 0) {
                    throw new CrmebException("折扣率不得输入小于等于0的数字");
                }
            }

            List<Integer> ids = request.getProductIdList();
            List<StoreProductMer> productMers = new ArrayList<>();
            List<StoreProductMer> storeProductMers = storeProductMerDao.selectList(Wrappers.<StoreProductMer>lambdaQuery()
                    .in(StoreProductMer::getProductId, ids)
            );
            Map<Integer, StoreProductMer> storeProductMerMap = storeProductMers.stream().collect(Collectors.toMap(StoreProductMer::getProductId, Function.identity(), (key1, key2) -> key2));
            for (Integer id : ids) {
                StoreProductMer storeProduct = storeProductMerMap.get(id);
                storeProduct = null == storeProduct ? new StoreProductMer() : storeProduct;
                storeProduct.setProductId(id);
                storeProduct.setPriceType(request.getType());
                if (1 == request.getType()) {
                    storeProduct.setPrice(request.getPrice());
                } else {
                    storeProduct.setPrice(request.getRatio() == null ? BigDecimal.ZERO : request.getRatio());
                }
                storeProduct.setUpdateTime(new Date());
                productMers.add(storeProduct);
                if (request.getType() == 1) {
                    List<StoreProductAttrValue> attrValues = storeProductAttrValueService.list(Wrappers.<StoreProductAttrValue>lambdaQuery()
                            .eq(StoreProductAttrValue::getProductId, storeProduct.getProductId())
                    );
                    List<StoreProductValueMer> productValueMerList = storeProductValueMerService.list(Wrappers.lambdaQuery(StoreProductValueMer.class).eq(StoreProductValueMer::getProductId, storeProduct.getProductId()));
                    Map<String, StoreProductValueMer> productValueMerMap = productValueMerList.stream().collect(Collectors.toMap(StoreProductValueMer::getSourceSkuId, e -> e));
                    for (StoreProductAttrValue sku : attrValues) {
                        StoreProductValueMer valueMer = productValueMerMap.get(sku.getSourceSkuId());
                        if (null == valueMer) {
                            valueMer = new StoreProductValueMer();
                            valueMer.setProductId(storeProduct.getProductId());
                            valueMer.setSourceSkuId(sku.getSourceSkuId());
                            valueMer.setVolume(sku.getVolume());
                        }
                        valueMer.setPrice(storeProduct.getPrice());
                        valueMer.setCreateTime(new Date());
                        valueMer.setUpdateTime(new Date());
                        storeProductValueMerService.saveOrUpdate(valueMer);
                    }
                }
            }
            boolean update = this.saveOrUpdateBatch(productMers);
            return update ? CommonResult.success() : CommonResult.failed();
        }
    }

    /**
     * 重置为分类加价率
     *
     * @param productId
     * @param merId
     * @return
     */
    @Override
    public CommonResult<Object> resetPrice(Integer productId, Integer merId) {
        StoreProductMer storeProductMer = getOne(Wrappers.lambdaQuery(StoreProductMer.class)
                .eq(StoreProductMer::getProductId, productId)
        );
        if (null == storeProductMer) {
            return CommonResult.success();
        }
        boolean update = update(Wrappers.lambdaUpdate(StoreProductMer.class)
                .eq(StoreProductMer::getProductId, productId)
                .set(StoreProductMer::getPriceType, 0).set(StoreProductMer::getPrice, BigDecimal.ZERO).set(StoreProductMer::getUpdateTime, new Date()));
        return update ? CommonResult.success() : CommonResult.failed();
    }

    /**
     * 价格尾号设置
     *
     * @param merId
     * @param request
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Object> batchPriceTailNumber(Integer merId, BatchPriceTailRequest request) {
        if (Objects.isNull(request.getPriceTailNumber())) {
            throw new CrmebException("价格尾号不能为空!!");
        }
        // 全部商品
        if (request.getType() == 1) {
            return batchPriceTailNumberClear(merId, request);
        }
        if (CollectionUtils.isEmpty(request.getProductIdList())) {
            throw new CrmebException("商品id不能为空!!");
        }

        List<Integer> ids = request.getProductIdList();
        List<StoreProductMer> productMers = new ArrayList<>();
        Date currentDate = new Date();

        List<StoreProductMer> list = storeProductMerDao.selectList(Wrappers.lambdaQuery(StoreProductMer.class)
                .in(StoreProductMer::getProductId, ids)
        );
        // 设置尾号
        list.forEach(storeProduct -> {
            storeProduct.setUpdateTime(currentDate);
            storeProduct.setPriceTailNumber(request.getPriceTailNumber());
            productMers.add(storeProduct);
        });
        List<Integer> productIdList = list.stream().map(StoreProductMer::getProductId).collect(Collectors.toList());
        // 取差集
        List<Integer> reduceIds = ids.stream().filter(item -> !productIdList.contains(item)).collect(Collectors.toList());
        reduceIds.forEach(id -> {
            StoreProductMer storeProduct = new StoreProductMer();
            storeProduct.setProductId(id);
            storeProduct.setPriceTailNumber(request.getPriceTailNumber());
            storeProduct.setUpdateTime(currentDate);
            productMers.add(storeProduct);
        });
        boolean update = this.saveOrUpdateBatch(productMers);
        return update ? CommonResult.success() : CommonResult.failed();
    }

    /**
     * 价格尾号清除
     *
     * @param merId
     * @param request
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Object> batchPriceTailNumberClear(Integer merId, BatchPriceTailRequest request) {
        LambdaUpdateWrapper<StoreProductMer> wrapper = new LambdaUpdateWrapper();
        // 处理全部商品
        if (request.getType() == 1) {
            updateChannelMerchant(merId, request);
            wrapper.isNotNull(StoreProductMer::getProductId);
            wrapper.set(StoreProductMer::getPriceTailNumber, null);
        } else {
            if (CollectionUtils.isEmpty(request.getProductIdList())) {
                throw new CrmebException("商品id不能为空!!");
            }
            wrapper.in(StoreProductMer::getProductId, request.getProductIdList());
            wrapper.set(StoreProductMer::getPriceTailNumber, -1);
        }
        boolean update = this.update(wrapper);
        return update ? CommonResult.success() : CommonResult.failed();
    }

    @Override
    public void createTable(String tableName) {
        storeProductMerDao.createTable(tableName);
    }

    /**
     * 功能描述: 商户自建商品修改零售价
     *
     * @Param: [requests]
     * @Return: java.lang.Boolean
     * @Author: wangzh
     * @Date: 2022/12/28 13:53
     */
    @Override
    public Boolean updatePriceByOneself(List<StoreProductOneselfRequest> requests) {
        StoreProduct storeProduct = new StoreProduct();
        StoreProductAttrValue one = storeProductAttrValueService.getOne(Wrappers.<StoreProductAttrValue>lambdaQuery()
                .eq(StoreProductAttrValue::getSourceSkuId, requests.get(0).getSourceSkuId())
                .groupBy(StoreProductAttrValue::getProductId)
                .last("limit 1"));
        storeProduct.setId(one.getProductId());
        BigDecimal minPrice = requests.get(0).getPrice();
        //设置每个规格的价格
        for (StoreProductOneselfRequest request : requests) {
            //最低价
            if (minPrice.compareTo(request.getPrice()) > 0) {
                minPrice = request.getPrice();
            }
            storeProductAttrValueService.update(Wrappers.<StoreProductAttrValue>lambdaUpdate()
                    .eq(StoreProductAttrValue::getSourceSkuId, request.getSourceSkuId())
                    .set(StoreProductAttrValue::getPrice, request.getPrice()));
        }
        //设置主商品的价格
        storeProduct.setPrice(minPrice);
        return storeProductService.updateById(storeProduct);
    }

    /**
     * 更新商户全部商品价格尾号
     *
     * @param merId
     * @param request
     * @return
     */
    private boolean updateChannelMerchant(Integer merId, BatchPriceTailRequest request) {
        LambdaUpdateWrapper<ChannelMerchant> wrapper = new LambdaUpdateWrapper();
        wrapper.eq(ChannelMerchant::getId, merId);
        wrapper.set(ChannelMerchant::getPriceTailNumber, request.getPriceTailNumber());
        boolean update = channelMerchantService.update(wrapper);
        return update;
    }

    /**
     * 云仓商品发货地国内的 移动到商户表内
     */
    @Override
    public Boolean buildCNGoods(Integer merId) {

        try {

            //建立字段
            Boolean flg = storeProductMerUtil.makeColumnsTwo(merId);

            if (flg) {
                //保存商品数据
                updateCNGoods(merId);

                //下架自建云仓商品
                downSelfBuildGoods();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;

    }

    public Boolean updateCNGoods(Integer merId) {

        //获取
        ChannelMerchant channelMerchant = channelMerchantService.getById(merId);

        if (null != channelMerchant) {

            SystemConfig systemConfig = systemConfigService.getOne(Wrappers.<SystemConfig>lambdaQuery()
                    .eq(SystemConfig::getName, "buildCNData_" + merId)
                    .last("LIMIT 1")
            );

            //可见配置
            List<Integer> brandIdsList = JSON.parseArray(channelMerchant.getBrandIds(), Integer.class);
            List<Integer> suppliersIdList = JSON.parseArray(channelMerchant.getSuppliersIds(), Integer.class);
            List<Integer> tempIdList = JSON.parseArray(channelMerchant.getTempId(), Integer.class);
            //不可见分类
            List<Integer> cateIdList = categoryMatchService.selectCategoryMatchDisable(merId).stream().map(CategoryMatch::getId).collect(Collectors.toList());

            LambdaQueryWrapper<StoreProduct> lambdaQueryWrapper = Wrappers.<StoreProduct>lambdaQuery()
                    .eq(StoreProduct::getIsShow, 1)
                    .ne(StoreProduct::getIsEurope, 1)     //云仓商品
                    .eq(StoreProduct::getTempId, StockAreaTempEnum.CN.getTempId())    //发货地国内的云仓商品
//                    .gt(StoreProduct::getId,18397366)   //测试使用
                    .gt(StoreProduct::getStock, 0);

            if (CollectionUtils.isNotEmpty(brandIdsList)) {
                lambdaQueryWrapper.in(StoreProduct::getBrandId, brandIdsList);
            }
            if (CollectionUtils.isNotEmpty(suppliersIdList)) {
                lambdaQueryWrapper.in(StoreProduct::getSuppliersId, suppliersIdList);
            }
            if (CollectionUtils.isNotEmpty(tempIdList)) {
                lambdaQueryWrapper.in(StoreProduct::getTempId, tempIdList);
            }
            if (CollectionUtils.isNotEmpty(cateIdList)) {
                lambdaQueryWrapper.notIn(StoreProduct::getCateId, cateIdList);
            }

            if (ObjectUtil.isNotNull(systemConfig) && "1".equals(systemConfig.getValue())) {    //执行过操作 后面就是增量
                log.info("--------------- 第二次处理 ---------------");
                lambdaQueryWrapper.notInSql(StoreProduct::getId, "SELECT product_id FROM " + TableNameUtil.getProductMerName(merId));
            }

            int count = storeProductDao.selectCount(lambdaQueryWrapper);

            int pageNo = 1;
            int pageSize = 100;
            int maxPage = (count + pageSize - 1) / pageSize;

            log.info("--------------- 开始分页查询云仓商品, 本次更新总条数为: {} ---------------", count);

            long millis = System.currentTimeMillis();
            while (pageNo <= maxPage) {
                try {
                    PageHelper.startPage(pageNo, pageSize);
                    List<StoreProduct> storeProducts = storeProductDao.selectList(lambdaQueryWrapper);
                    PageInfo<StoreProduct> pageInfo = PageInfo.of(storeProducts);
                    List<StoreProduct> products = pageInfo.getList();
                    buildProduct(products, merId);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                log.info("--------------- 发货地国内的云仓商品下发到商户商品表, 当前页数: {}, 总页数: {}, 耗时: {} 分 ---------------",
                        pageNo, maxPage, (int) ((System.currentTimeMillis() - millis) / 1000 / 60));
                pageNo++;
            }

            //执行完后
            if (ObjectUtil.isNotNull(systemConfig)) {
                systemConfigService.update(Wrappers.<SystemConfig>lambdaUpdate()
                        .eq(SystemConfig::getId, systemConfig.getId())
                        .set(SystemConfig::getValue, 1)
                );
            } else {
                log.info("--------------- 第一次保存systemConfig ---------------");

                systemConfig = new SystemConfig("buildCNData_" + merId
                        , "商户商品导入flg"
                        , 100
                        , "1"
                        , false);
                systemConfigService.save(systemConfig);

            }
        }

        return true;

    }

    /**
     * 商品构建处理
     *
     * @param @param products
     * @return void
     * @throws
     * @Description:
     * @author daigb
     */
    private void buildProduct(List<StoreProduct> products, Integer merId) {

        for (StoreProduct storeProduct : products) {

            StoreProductNormResponse storeProductResponse = merStoreProductService.getSupplierByProductId(storeProduct.getId(), merId);

            StoreProductMerRequest storeProductMerRequest = new StoreProductMerRequest();

            List<StoreProductMer> storeProductMers = new ArrayList<>();

            for (StoreProductResponse storeProductData : storeProductResponse.getProducts()) {

                StoreProductMer storeProductMer = new StoreProductMer();

                storeProductMer.setProductId(storeProductData.getId());
                storeProductMer.setRecommendImg(null);
                storeProductMer.setPriceType(0);
//                storeProductMer.setShippingTempId(1);
                List<StoreProductValueMer> storeProductValueMerList = new ArrayList<>();

                for (StoreProductAttrValueResponse storeProductAttrValueResponse : storeProductData.getAttrValue()) {

                    StoreProductValueMer storeProductValueMer = new StoreProductValueMer();

                    storeProductValueMer.setId(null);
                    storeProductValueMer.setProductId(storeProductAttrValueResponse.getProductId());
                    storeProductValueMer.setPrice(storeProductAttrValueResponse.getPrice());
                    storeProductValueMer.setSourceSkuId(storeProductAttrValueResponse.getSourceSkuId());
                    // storeProductValueMer.setWeight(new BigDecimal(4));
                    // storeProductValueMer.setVolume(new BigDecimal(5));
                    storeProductValueMerList.add(storeProductValueMer);

                }

                storeProductMer.setStoreProductValueMerList(storeProductValueMerList);

                storeProductMers.add(storeProductMer);

            }
            storeProductMerRequest.setStoreProductMers(storeProductMers);

            updateStoreProductMer(storeProductMerRequest, merId);

        }

    }

    private Boolean updateStoreProductMer(StoreProductMerRequest storeProductMerRequest, Integer merId) {
        List<StoreProductMer> storeProductMers = storeProductMerRequest.getStoreProductMers();
        List<StoreProductMer> storeProductMerSaves = new ArrayList<>();

        for (StoreProductMer merRequest : storeProductMers) {

            Boolean is_insert = false;

            StoreProductMer storeProductMer = this.getOne(Wrappers.<StoreProductMer>lambdaQuery()
                    .eq(StoreProductMer::getProductId, merRequest.getProductId())
                    .last("LIMIT 1")
            );

            if (null == storeProductMer) {

                storeProductMer = new StoreProductMer();

                storeProductMer.setIsNotShow("1");   //下架

                is_insert = true;

            } else {
                if (ObjectUtil.isNull(storeProductMer.getShippingTempId())) {
                    storeProductMer.setIsNotShow("1");   //下架
                }
            }

            storeProductMer.setProductId(merRequest.getProductId());
            storeProductMer.setRecommendImg(merRequest.getRecommendImg());

            if (Objects.equals(merRequest.getPriceType(), PriceTypeEnum.FIXED.getCode()) && CollectionUtils.isNotEmpty(merRequest.getStoreProductValueMerList())) {
                List<StoreProductValueMer> productValueMerList = new ArrayList<>();

                for (StoreProductValueMer storeProductValueMer : merRequest.getStoreProductValueMerList()) {

                    StoreProductValueMer productValueMer = storeProductValueMerService.getOne(Wrappers.lambdaQuery(StoreProductValueMer.class)
                            .eq(StoreProductValueMer::getProductId, merRequest.getProductId())
                            .eq(StoreProductValueMer::getSourceSkuId, storeProductValueMer.getSourceSkuId()));

                    if (productValueMer == null) {

                        productValueMer = new StoreProductValueMer();

                        productValueMer.setPrice(storeProductValueMer.getPrice());
                    }

                    productValueMer.setProductId(merRequest.getProductId())
                            .setSourceSkuId(storeProductValueMer.getSourceSkuId());
                    productValueMerList.add(productValueMer);
                }
                //查询sku实时库存,获取最低价格
                if (is_insert) {

                    List<StoreProductAttrValue> storeProductAttrValueList = storeProductAttrValueService.list(Wrappers.lambdaQuery(StoreProductAttrValue.class).eq(StoreProductAttrValue::getProductId, merRequest.getProductId()).gt(StoreProductAttrValue::getStock, 0));
                    List<String> list = storeProductAttrValueList.stream().map(StoreProductAttrValue::getSourceSkuId).collect(Collectors.toList());
                    BigDecimal minPrice;
                    if (CollectionUtils.isNotEmpty(list)) {
                        minPrice = merRequest.getStoreProductValueMerList().stream().filter(e -> list.contains(e.getSourceSkuId())).map(StoreProductValueMer::getPrice).filter(Objects::nonNull).min(BigDecimal::compareTo).orElse(BigDecimal.ZERO);
                    } else {
                        minPrice = merRequest.getStoreProductValueMerList().stream().map(StoreProductValueMer::getPrice).filter(Objects::nonNull).min(BigDecimal::compareTo).orElse(BigDecimal.ZERO);
                    }
                    storeProductMer.setPrice(minPrice);

                }

                storeProductValueMerService.saveOrUpdateBatch(productValueMerList);
                storeProductMer.setPriceType(merRequest.getPriceType());

            }
            storeProductMerSaves.add(storeProductMer);
        }

        return this.saveOrUpdateBatch(storeProductMerSaves);
    }

    @Override
    public List<Integer> selectShippingTempId(String tableName) {

        return storeProductMerDao.selectShippingTempId(tableName);
    }

    @Override
    public void addShippingTempId(String tableName) {

        storeProductMerDao.addShippingTempId(tableName);
    }

    //自建商品没有运费模板下架
    @Override
    public Boolean downSelfBuildGoods() {

        try {

            storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate()
                    .eq(StoreProduct::getIsEurope, 1)   //自建商品
                    .isNull(StoreProduct::getShippingTempId)    //没有模板id
                    .set(StoreProduct::getIsShow, 0));

        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;

    }

    @Override
    public Boolean saveOrUpdateGoods(String tableName, StoreProductMer storeProductMer) {
        return this.baseMapper.saveOrUpdateGoods(tableName, storeProductMer);
    }

    @Override
    public Boolean removeGoods(String tableName, List<Integer> productIds) {
        return this.baseMapper.removeGoods(tableName, productIds);
    }
}
